#pragma once
#include <string>

namespace krryn{
namespace core{
	class job_manager;
}
namespace scene{
	class mesh;
}
namespace view{
	class shader_catalog;
	class shader;
}
namespace math{
	class matrix;
}
namespace view{
	class camera;
}
namespace system{
	class input_manager;
    class renderer{
	public:
		renderer(core::job_manager *a_Manager) : m_Manager(a_Manager), m_Catalog(0) {}
		virtual ~renderer();

		virtual input_manager* get_input_manager() = 0;

		virtual void begin_scene() = 0;
		virtual void draw(scene::mesh *a_Mesh, const math::matrix &a_Transformation) = 0;
		virtual void end_scene() = 0;

		// Subclasses should initialize m_Catalog once in this function
		// with the concrete shader catalog and then return m_Catalog.
		virtual view::shader_catalog* get_shader_catalog() = 0;
		view::shader* get_shader(const std::string &a_Name);

		virtual void set_projection_matrix(const math::matrix &a_ProjectionMatrix) = 0;
		virtual void set_camera(view::camera *a_Camera) = 0;
	protected:
		core::job_manager *m_Manager;

		// Notice: this is not a static variable because the catalog 
		// might not be sharable between rendering contexts.
		view::shader_catalog *m_Catalog;
    };
}
}
